package com.resjz.milddog.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.resjz.milddog.service.UserLoginService;
import com.resjz.milddog.utils.AuthToken;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.apache.oltu.oauth2.common.message.types.ResponseType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;

import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service

public class UserLoginServiceImpl implements UserLoginService {

    //实现请求发送
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private DiscoveryClient discoveryClient;
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * 用户登录验证(密码模式)
     * @param username
     * @param password
     * @param clientId
     * @param clientSecret
     * @param grant_type
     */
    @Override
    public JSONObject login(String username, String password, String clientId, String clientSecret, String grant_type) throws Exception {
        List<ServiceInstance> instance = discoveryClient.getInstances("milddog_auth");
        ServiceInstance serviceInstance = instance.get(0);
        JSONObject result = new JSONObject();
        OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
        OAuthClientRequest codeTokenRequest = OAuthClientRequest
                .authorizationLocation(serviceInstance.getUri()+"/oauth/authorize")
                .setResponseType(ResponseType.CODE.toString())
                .setClientId(clientId)
                .setRedirectURI("http://"+serviceInstance.getUri()+"/fallBack/code")
                .buildQueryMessage();
        //获取 code
        OAuthResourceResponse codeResponse = oAuthClient.resource(
                codeTokenRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
        if(codeResponse.getResponseCode() != HttpServletResponse.SC_OK) {
            result.put("code", codeResponse.getResponseCode());
            result.put("msg", codeResponse.getBody());
        } else {
            String url =serviceInstance.getUri()+ "/login";
            Map<String, String> params = new HashMap<>();
            params.put("username", username);
            params.put("password", password);

            HttpPost httpPost = new HttpPost(url);
            //添加http头信息
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            params.forEach((k, v) -> {
                builder.addPart(k, new StringBody(v, ContentType.MULTIPART_FORM_DATA));
            });
            HttpEntity postEntity = (HttpEntity) builder.build();
            httpPost.setEntity(postEntity);
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            HttpResponse execute = closeableHttpClient.execute(httpPost);
            Header location = execute.getFirstHeader("Location");
            CloseableHttpResponse execute1 = closeableHttpClient.execute(new HttpGet(location.getValue()+"/login"));
            System.out.println("111111");
            OAuthClientRequest codeTokenRequest2 = OAuthClientRequest
                    .authorizationLocation(serviceInstance.getUri()+"/oauth/authorize")
                    .setResponseType(ResponseType.CODE.toString())
                    .setClientId(clientId)
                    .setRedirectURI(serviceInstance.getUri()+"/fallBack/code")
                    .buildQueryMessage();
            System.out.println("111111");
            /*String authCode = codeResponse.getBody();
            OAuthClientRequest accessTokenRequest = OAuthClientRequest
                    .tokenLocation(serviceInstance.getUri()+"/oauth/accessToken")
                    .setGrantType(GrantType.AUTHORIZATION_CODE)
                    .setClientId(clientId)
                    .setClientSecret(clientSecret)
                    .setCode(authCode)
                    .setRedirectURI(serviceInstance.getUri()+"/fallBack/code")
                    .buildQueryMessage();
            //获取access token
            OAuthAccessTokenResponse tokenResponse =
                    oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);*/
            /*if(tokenResponse.get != HttpServletResponse.SC_OK) {
                result.put("code", tokenResponse.getResponseCode());
                result.put("msg", tokenResponse.getBody());
                return result;
            } else {
                //验证token
                OAuthClientRequest validateRequest =
                        new OAuthBearerClientRequest("http://127.0.0.1:8080/auth-web/oauth/validate")
                                .setAccessToken(tokenResponse.getAccessToken()).buildQueryMessage();
                OAuthResourceResponse validateResponse = oAuthClient.resource(
                        validateRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
                if(validateResponse.getResponseCode() != HttpServletResponse.SC_OK) {
                    result.put("code", validateResponse.getResponseCode());
                    result.put("msg", validateResponse.getBody());
                } else {
                    JSONObject body = JSON.parseObject(validateResponse.getBody());
                    result.put("code", body.getString("code"));
                    result.put("msg", body.getString("msg"));
                }
            }*/
            System.out.println("1111111111111");
        }
        return result;
        /*//获取指定服务的注册数据
        List<ServiceInstance> instance = discoveryClient.getInstances("milddog_auth");
        ServiceInstance serviceInstance = instance.get(0);
//        //调用请求地址
        String url = serviceInstance.getUri()+"/oauth/token";
//          String url = "http://localhost:9200/oauth/token";


        //请求提交的数据分装
        MultiValueMap<String,String> paramMap = new LinkedMultiValueMap<>();
        paramMap.add("username",username);
        paramMap.add("password",password);
        paramMap.add("grant_type",grant_type);

        //请求头封装
        String authorization = "Basic "+ new String(Base64.getEncoder().encode((clientId+":"+ BCrypt.hashpw(clientSecret,BCrypt.gensalt())).getBytes()),"UTF-8");
        MultiValueMap<String,String> headerMap = new LinkedMultiValueMap();
        headerMap.add("Authorization",authorization);

        //创建HttpEntity->创建该对象 分装请求头和请求体
        HttpEntity httpEntity = new HttpEntity(paramMap, headerMap);
        *//**
         * 1.请求地址
         * 2.请求方式
         * 3.请求提交的数据信息分装  请求体&&请求头
         * 4，返回数据需要转换的类型
         *//*
        try{
            ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Map.class);
            Map<String,String> map = responseEntity.getBody();
            System.out.println(map);
            AuthToken authToken = new AuthToken();
//        authToken.setAccessToken(map.get("access_token").toString());
//        authToken.setRefreshToken(map.get("refresh_token").toString());
//        authToken.setJti(map.get("jti").toString());
            return authToken;
        } catch (Exception e){
            e.printStackTrace();
            System.out.println(e);
            System.out.println(e.getMessage());

        }

        return null;*/


        /*List<ServiceInstance> instance = discoveryClient.getInstances("milddog_auth");
        ServiceInstance serviceInstance = instance.get(0);

        Map<String, String> params = new HashMap<>();

        params.put("username", username);
        params.put("password", password);
        String locationUrl = serviceInstance.getUri()+"/oauth/authorize?client_id=" + clientId + "&response_type=code"+"&redirect_uri=http://"+serviceInstance.getUri()+"/fallBack/code";
        String url =serviceInstance.getUri()+ "/login";
        String result = "";


        try {
            // 创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            HttpPost httpPost = new HttpPost(url);
            HttpPost post = new HttpPost(locationUrl);
            //添加http头信息
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            params.forEach((k, v) -> {
                builder.addPart(k, new StringBody(v, ContentType.MULTIPART_FORM_DATA));
            });
            HttpEntity postEntity = (HttpEntity) builder.build();
            httpPost.setEntity(postEntity);
            HttpEntity entity = null;
            try {
                //第一步:执行登录(用户名密码)(注意是POST请求方式),结果是302
                closeableHttpClient.execute(httpPost);
                //第二步:重定向,直接输入auth/login进行登录时,Location是auth的根目录,而我们需要跳转到(注意是POST请求方式)
                // /oauth/authorize?client_id=" + client_id + "&response_type=" + response_type这个路径,才能获取code,,结果是302还需要再次重定向
                HttpResponse execute = closeableHttpClient.execute(post);
                //这里我做了重定向到我自己的方法，这个是oauth2设置的回调地址
                //http://192.168.2.18:9001/fallBack/code（web_server_redirect_uri）,
                //直接将code通过后台换取access_token(注意是GET请求方式)
                Header location = execute.getFirstHeader("Location");
                CloseableHttpResponse execute1 = closeableHttpClient.execute(new HttpGet(location.getValue()));
                entity = execute1.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity);
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 关闭连接
            closeableHttpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = JSON.parseObject(result);


        return jsonObject;*/

    }
}
